package design.onekey.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.util.StringUtil;
import design.onekey.base.*;
import design.onekey.constant.enums.DelFlagEnum;
import design.onekey.constant.enums.RedisPerfixEnum;
import design.onekey.constant.StatusCode;
import design.onekey.exception.BizException;
import design.onekey.mapper.SysCodeValueMapper;
import design.onekey.model.SysCodeValue;
import design.onekey.model.dto.UserInfoDto;
import design.onekey.service.ISysCodeValueService;
import design.onekey.util.MessageUtil;
import design.onekey.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author
 * @version V1.0
 * @Description: SysCodeValue服务实现
 * @date 2020-06-05 04:02:24
 */
@Service
public class SysCodeValueServiceImpl extends ServiceImpl<SysCodeValueMapper, SysCodeValue> implements ISysCodeValueService {

    @Autowired
    private RedisUtil redisUtil;

    /**
     * @param @param model
     * @return BaseEntity
     * @throws
     * @Title: tablePagingQuery
     * @Description: 表格分页查询
     * @author
     */
    @Override
    public PageEntity tablePagingQuery(SysCodeValue model) {
        PageEntity result = new PageEntity();
        model.setDelFlag(DelFlagEnum.UNDEL.getCode());
        com.github.pagehelper.Page<?> page = PageHelper.startPage(model.getCurrentPage(), model.getPageSize()); //分页条件
        List<SysCodeValue> list = this.baseMapper.searchDataLike(model);
        result.setData(list);
        result.setTotal(page.getTotal());
        result.setCurrentPage(model.getCurrentPage());
        result.setPageSize(model.getPageSize());
        return result;
    }


    /**
     * <p>Title: getDetail</p>
     * <p>Description: 获取详情</p>
     *
     * @param id
     * @return
     * @author
     */
    @Override
    public BaseEntity getDetail(Long id) {
        return this.getById(id);
    }

    /**
     * <p>Title: insert</p>
     * <p>Description: 新增数据</p>
     *
     * @param model
     * @return
     * @author
     */
    @Transactional
    @Override
    public BaseEntity insert(SysCodeValue model, UserInfoDto userInfoDto) {
        //检查重复
        QueryWrapper<SysCodeValue> queryWrapper =
                new QueryWrapper<SysCodeValue>().eq("code_type", model.getCodeType())
                        .eq("code_value", model.getCodeValue()).eq("del_flag", DelFlagEnum.UNDEL.getCode());
        Function<QueryWrapper<SysCodeValue>, Boolean> function = p -> this.baseMapper.selectCount(p) != 0;
        if (checkRepeat(queryWrapper, function)) {
            throw new BizException(StatusCode.CHECK_FAILURE, MessageUtil.getValue("error.check.exist", new String[]{"字典类别对应的名称"}));
        }
        //查询最大sort
        Integer i = this.baseMapper.selectMaxSort(model.getCodeType());
        if (i == null) {
			i = 0;
		}
        BaseEntity result = new BaseEntity();
        model.setSort(++i);
        this.save(model);
        //更新缓存
        try {
            //获取原来的缓存
            List<SysCodeValue> sysCodeValues = (List<SysCodeValue>) redisUtil.get(RedisPerfixEnum.SYSCODETYPE.getCode() + model.getCodeType());
            SysCodeValue sysCodeValue = this.baseMapper.selectById(model.getId());
            //判断原来是否有值
            if (null != sysCodeValues && sysCodeValues.size() > 0) {
                sysCodeValues.add(sysCodeValue);
                //重新赋值
                redisUtil.set(RedisPerfixEnum.SYSCODETYPE.getCode() + model.getCodeType(), sysCodeValues);
            } else {
                //new
                redisUtil.set(RedisPerfixEnum.SYSCODETYPE.getCode() + model.getCodeType(), Arrays.asList(sysCodeValue));
            }
            //codeType:codeValue
            redisUtil.set(RedisPerfixEnum.SYSCODEVALUE.getCode() + model.getCodeType()+":"+model.getCodeValue(), sysCodeValue.getCodeValueName());
            //codeType:codeValue
//            redisUtil.set(RedisPerfixEnum.SYSCODETYPEVALUE.getCode() + model.getCodeType()+model.getCodeValue(), model.getId());
        } catch (Exception e) {
            e.printStackTrace();
        }

        result.setStatusMsg(MessageUtil.getValue("info.insert"));
        return result;
    }

    /**
     * <p>Title: update</p>
     * <p>Description: 更新数据</p>
     *
     * @param model
     * @return
     * @author
     */
    @Transactional
    @Override
    public BaseEntity update(SysCodeValue model, UserInfoDto userInfoDto) {
        //检查重复
        QueryWrapper<SysCodeValue> queryWrapper =
                new QueryWrapper<SysCodeValue>().eq("code_type", model.getCodeType()).ne("id", model.getId())
                        .eq("code_value", model.getCodeValue()).eq("del_flag", DelFlagEnum.UNDEL.getCode());
        Function<QueryWrapper<SysCodeValue>, Boolean> function = p -> this.baseMapper.selectCount(p) != 0;
        if (checkRepeat(queryWrapper, function)) {
            throw new BizException(StatusCode.CHECK_FAILURE, MessageUtil.getValue("error.check.exist", new String[]{"字典类别对应的名称"}));
        }
        BaseEntity result = new BaseEntity();
        model.setSort(null);
        this.updateById(model);
        //更新缓存
        try {
            //获取原来的缓存
            List<SysCodeValue> sysCodeValues = (List<SysCodeValue>) redisUtil.get(RedisPerfixEnum.SYSCODETYPE.getCode() + model.getCodeType());
            if (null != sysCodeValues && sysCodeValues.size() > 0) {
                //id唯一
                List<SysCodeValue> collect = sysCodeValues.stream()
                        .filter(p -> p.getId().longValue() == model.getId().longValue()).collect(Collectors.toList());
                SysCodeValue sysCodeValueO = collect.get(0);
                sysCodeValues.remove(sysCodeValueO);
                SysCodeValue sysCodeValueN = this.baseMapper.selectById(model.getId());
                sysCodeValues.add(sysCodeValueN);
                redisUtil.set(RedisPerfixEnum.SYSCODETYPE.getCode() + model.getCodeType(), sysCodeValues);
                //更新codeValue
//				if (model.getCodeValueName()!=null){
                redisUtil.set(RedisPerfixEnum.SYSCODEVALUE.getCode() + model.getCodeType()+":"+model.getCodeValue(), model.getCodeValueName());
                //codeType:codeValue
//                redisUtil.set(RedisPerfixEnum.SYSCODETYPEVALUE.getCode() + model.getCodeType()+model.getCodeValue(), model.getId());
//				}
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        result.setStatusMsg(MessageUtil.getValue("info.update"));
        return result;
    }

    /**
     * <p>Title: delete</p>
     * <p>Description: 单条删除数据</p>
     *
     * @param model
     * @return
     * @author
     */
    @Transactional
    @Override
    public BaseEntity delete(Long id) {
        SysCodeValue sysCodeValue = new SysCodeValue();
        sysCodeValue.setId(id);
        sysCodeValue.setDelFlag(DelFlagEnum.DEL.getCode());
        this.updateById(sysCodeValue);
        BaseEntity result = new BaseEntity();
        //更新缓存
        try {
            SysCodeValue sysCodeValueO = this.baseMapper.selectById(id);
            //删除type列表里的值
            List<SysCodeValue> codeValues =
                    (List<SysCodeValue>) redisUtil.get(RedisPerfixEnum.SYSCODETYPE.getCode() + sysCodeValueO.getCodeType());
            if (null != codeValues && codeValues.size() > 0) {
                //id 唯一
                SysCodeValue sysCodeValue1 = codeValues.stream().filter(p -> p.getId().longValue() == id).collect(Collectors.toList()).get(0);
                codeValues.remove(sysCodeValue1);
                redisUtil.set(RedisPerfixEnum.SYSCODETYPE.getCode() + sysCodeValueO.getCodeType(), codeValues);
            }
            redisUtil.del(RedisPerfixEnum.SYSCODEVALUE.getCode() + id);
        } catch (Exception e) {
            e.printStackTrace();
        }
        result.setStatusMsg(MessageUtil.getValue("info.delete"));
        return result;
    }

    /**
     * <p>Title: deleteBatch</p>
     * <p>Description: 批量删除数据</p>
     *
     * @param list
     * @return
     * @author
     */
    @Transactional
    @Override
    public BaseEntity deleteBatch(List<Long> ids) {
        List<SysCodeValue> list = new ArrayList<SysCodeValue>();
        for (int i = 0; i < ids.size(); i++) {
            SysCodeValue sysCodeValue = new SysCodeValue();
            sysCodeValue.setId(ids.get(i));
            sysCodeValue.setDelFlag(DelFlagEnum.DEL.getCode());
            list.add(sysCodeValue);
        }
        BaseEntity result = new BaseEntity();
        if (list != null && list.size() > 0) {
            this.updateBatchById(list);
        }
        ids.forEach(id -> {
            //更新缓存
            try {
                SysCodeValue sysCodeValueO = this.baseMapper.selectById(id);
                //删除type列表里的值
                List<SysCodeValue> codeValues =
                        (List<SysCodeValue>) redisUtil.get(RedisPerfixEnum.SYSCODETYPE.getCode() + sysCodeValueO.getCodeType());
                if (null != codeValues && codeValues.size() > 0) {
                    //id 唯一
                    SysCodeValue sysCodeValue1 = codeValues.stream().filter(p -> p.getId().longValue() == id).collect(Collectors.toList()).get(0);
                    codeValues.remove(sysCodeValue1);
                    redisUtil.set(RedisPerfixEnum.SYSCODETYPE.getCode() + sysCodeValueO.getCodeType(), codeValues);
                }
                redisUtil.del(RedisPerfixEnum.SYSCODEVALUE.getCode() + id);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        result.setStatusMsg(MessageUtil.getValue("info.delete"));
        return result;
    }

    /**
     * @Method selectValByType
     * @Author zhangcheng
     * @Version 1.0
     * @Description 根据codeType查询codeval
     * @Return com.baiyyy.yfz.base.BaseEntity
     * @Exception
     * @Date 2020-6-17 16:05
     */
    @Override
    public List<SysCodeValue> selectValByType(String codeType) {
        //首先查询缓存
        List<SysCodeValue> sysCodeValues;
        try {
            sysCodeValues = (List<SysCodeValue>) redisUtil.get(RedisPerfixEnum.SYSCODETYPE.getCode() + codeType);
            if (sysCodeValues != null && !sysCodeValues.isEmpty()) {
                return sysCodeValues;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //查询数据库
        QueryWrapper<SysCodeValue> queryWrapper =
                new QueryWrapper<SysCodeValue>().eq("code_type", codeType).eq("del_flag", DelFlagEnum.UNDEL.getCode());
        queryWrapper.orderByAsc("code_value");
        sysCodeValues = this.baseMapper.selectList(queryWrapper);
        return sysCodeValues;
    }

    /**
     * @Method getValueName
     * @Author zhangcheng
     * @Version 1.0
     * @Description 根据id查询valueName
     * @Return java.lang.String
     * @Exception
     * @Date 2020-6-17 16:13
     */
    @Override
    public String getValueName(String type,String value) {
        //查询缓存
		try {
			String valName = (String) redisUtil.get(RedisPerfixEnum.SYSCODEVALUE.getCode() + type + ":" + value);
			if (StringUtil.isNotEmpty(valName)){
				return valName;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		QueryWrapper<SysCodeValue> queryWrapper = new QueryWrapper<SysCodeValue>();
		queryWrapper.eq("del_flag", DelFlagEnum.UNDEL.getCode());
		queryWrapper.eq("code_type", type);
		queryWrapper.eq("code_value", value);
		SysCodeValue sysCodeValue = this.baseMapper.selectOne(queryWrapper);
		if (sysCodeValue != null) {
			try {
				redisUtil.set(RedisPerfixEnum.SYSCODEVALUE.getCode()+type+":"+value, sysCodeValue.getCodeValueName());
			} catch (Exception e) {
				e.printStackTrace();
			}
			return sysCodeValue.getCodeValueName();
		}
		return "";
    }

	/**
	 * @Method getAllVal
	 * @Author zhangcheng
	 * @Version  1.0
	 * @Description 加载id：valueName
	 * @Return java.util.Map<java.lang.String,java.lang.String>
	 * @Exception
	 * @Date 2020-6-17 16:59
	 */
	@Override
	public Map<String, String> getAllVal() {
		Map<String, String> map = new HashMap<>();
		QueryWrapper<SysCodeValue> del_flag = new QueryWrapper<SysCodeValue>().eq("del_flag", DelFlagEnum.UNDEL.getCode());
		List<SysCodeValue> sysCodeValues = this.baseMapper.selectList(del_flag);
		sysCodeValues.forEach(p->{
			map.put(p.getCodeType()+":"+p.getCodeValue(),p.getCodeValueName());
		});
		return map;
	}


	/**
	 * @Title: getValuesName
	 * @Description: 获取多个值得name
	 * @param type
	 * @param values
	 * @return
	 * @author blcloak
	 * @date 2020-08-19 05:53:54
	 */
	@Override
	public List<String> getValuesName(String type, List<String> values) {
		List<String> keys = new ArrayList<>();
		List<String> result = new ArrayList<>();
		for (int i = 0; i < values.size(); i++) {
			String key = RedisPerfixEnum.SYSCODEVALUE.getCode() + type + ":" + values.get(i);
			keys.add(key);
		}
		try {
			List<Object> names = redisUtil.multiGet(keys);
			if(names != null && names.size()>0)
			{
				for (int i = 0; i < names.size(); i++) {
					result.add((String)names.get(i));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

}
